package com.cxyd.modules.wcs.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cxyd.common.constant.RcsConstants;
import com.cxyd.common.constant.WcsConstants;
import com.cxyd.common.service.impl.CrudServiceImpl;
import com.cxyd.common.utils.ProcResult;
import com.cxyd.modules.wcs.dao.AgvTrkHkDao;
import com.cxyd.modules.wcs.dao.AgvTrkYfDao;
import com.cxyd.modules.wcs.dao.PostWmsDao;
import com.cxyd.modules.wcs.dao.TrkDao;
import com.cxyd.modules.wcs.dto.TrkDTO;
import com.cxyd.modules.wcs.entity.*;
import com.cxyd.modules.wcs.service.PcItemService;
import com.cxyd.modules.wcs.service.PostWmsService;
import com.cxyd.modules.wcs.service.StnMappingService;
import com.cxyd.modules.wcs.service.TrkService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;

@Service
public class TrkServiceImpl extends CrudServiceImpl<TrkDao, TrkEntity, TrkDTO> implements TrkService {
    @Resource
    private PostWmsDao postWmsDao;
    @Resource
    private AgvTrkHkDao agvTrkHkDao;
    @Resource
    private AgvTrkYfDao agvTrkYfDao;
    @Resource
    private StnMappingService stnMappingService;
    @Resource
    private PcItemService pcItemService;

    @Override
    public QueryWrapper<TrkEntity> getWrapper(Map<String, Object> params) {
        String contNo = (String) params.get("contNo");
        String trkType = (String) params.get("trkType");
        String dvcNo = (String) params.get("dvcNo");
        String frmPos = (String) params.get("frmPos");
        String toPos = (String) params.get("toPos");
        QueryWrapper<TrkEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(dvcNo), "dvc_no", dvcNo);
        wrapper.eq(StringUtils.isNotBlank(trkType), "trk_type", trkType);
        wrapper.eq(StringUtils.isNotBlank(frmPos), "frm_pos", frmPos);
        wrapper.eq(StringUtils.isNotBlank(toPos), "to_pos", toPos);
        wrapper.like(StringUtils.isNotBlank(contNo), "cont_no", contNo);
        return wrapper;
    }

    @Override
    public TrkEntity selectByDvcNo(String dvcNo) {
        QueryWrapper<TrkEntity> qw = new QueryWrapper<>();
//        查找目标设备的初始搬送任务
        qw.lambda().eq(TrkEntity::getDvcNo, dvcNo)
                .eq(TrkEntity::getTrkSt, WcsConstants.TRK_STATUS_START)
                .last("limit 1");
        return baseDao.selectOne(qw);
    }

    @Override
    public TrkEntity selectByContNo(String contNo) {
        QueryWrapper<TrkEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(TrkEntity::getContNo, contNo)
                .last("limit 1");
        return baseDao.selectOne(qw);
    }

    @Override
    public void updateTrkByContNo(String contNo) {
//        1.根据托盘信息处理wcs_trk数据
        QueryWrapper<TrkEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(TrkEntity::getContNo, contNo)
                .eq(TrkEntity::getTrkSt, WcsConstants.TRK_STATUS_DONE);
        TrkEntity trkEntity = baseDao.selectOne(qw);
//        1.更新上报状态
        trkEntity.setFbSt(1);
        trkEntity.setUpdater(WcsConstants.WCS_USER_ID);
        trkEntity.setUpdateDate(new Date());
        baseDao.updateById(trkEntity);
//        2.转移数据至历史表[his_wcs_trk]
        baseDao.backupTrk(contNo);
//        3.删除当前数据
        baseDao.deleteById(trkEntity);
    }

    @Override
    public ProcResult trkHandler(Map<String, Object> params) {
//        接收任务ID已经操作方式
        String trkId = (String) params.get("trkId");
        String operateType = (String) params.get("operateType");
        if (StrUtil.isBlankIfStr(trkId)) {
            return new ProcResult().result("trkHandler_001", "主任务ID不能为空!");
        }
        if (StrUtil.isBlankIfStr(operateType)) {
            return new ProcResult().result("trkHandler_002", "作业类型不能为空!");
        }
//        判断任务是否存在(不存在报错)
        TrkEntity trkEntity = baseDao.selectById(trkId);
        if (trkEntity == null) {
            return new ProcResult().result("trkHandler_003", "主任务[" + trkId + "]不存在!");
        }
//        根据操作方式进行数据处理(REPEAT/DONE/CANCEL/DELETE)
        if (WcsConstants.TASK_FORCE_REPEAT_OPERATE.equals(operateType)) {
//          判断任务的状态是否能够重发(TODO)
//          只能重发异常状态的任务
            if (WcsConstants.TRK_STATUS_ERROR != trkEntity.getTrkSt()) {
                return new ProcResult().result("trkHandler_004", "只有[异常]状态下的任务允许重发!");
            }
//          将状态设置为初始
            trkEntity.setTrkSt(WcsConstants.TRK_STATUS_START);
//          备注信息人为操作
            trkEntity.setComments("人工将任务重新下发!");
//          更新时间
            trkEntity.setUpdateDate(new Date());
        } else if (WcsConstants.TASK_FORCE_DONE_OPERATE.equals(operateType)) {
            // 将海康agv任务设置成完成
            if (trkEntity.getDvcNo().equals("HK_AGV")) {
                StnMappingEntity stnByNo = stnMappingService.getStnByNo(trkEntity.getToPos());
                AgvTrkHkEntity agvTrkHkEntity = this.getAgvHkTrkByTrkId(trkEntity.getTrkId());
                if (ObjectUtils.isNotEmpty(agvTrkHkEntity)) {
                    agvTrkHkEntity.setStatus(RcsConstants.HK_STATUS_END); //任务完成
                    agvTrkHkEntity.setCurrentPositionCode(stnByNo.getWcsStation());
                    agvTrkHkEntity.setUpdateDate(new Date());
                    agvTrkHkDao.updateById(agvTrkHkEntity);
                }
            }
            // 将宇峰 agv任务设置成完成
            if (trkEntity.getDvcNo().equals("YF_AGV")) {
                AgvTrkYfEntity agvTrkYfEntity = this.getAgvYfTrkByTrkId(trkEntity.getTrkId());
                if (ObjectUtils.isNotEmpty(agvTrkYfEntity)) {
                    agvTrkYfEntity.setStatus(RcsConstants.HK_STATUS_END); //任务完成
                    agvTrkYfEntity.setUpdateDate(new Date());
                    agvTrkYfDao.updateById(agvTrkYfEntity);
                }
            }
//            将状态设置为完成
            trkEntity.setTrkSt(WcsConstants.TRK_STATUS_DONE);
            trkEntity.setComments("人工将任务强制完成!");
            trkEntity.setUpdateDate(new Date());
//      任务接收后上报wms系统[wcs_post_wms]
            PostWmsEntity postWms = new PostWmsEntity();
            postWms.setRequestPk(trkEntity.getRequestPk());
            postWms.setContNo(trkEntity.getContNo());
            postWms.setCurPos(trkEntity.getToPos());
//        类型为[完成]
            postWms.setNoticeType(WcsConstants.POST_TYPE_DONE);
            postWms.setCode("0");
            postWms.setResult("人工将任务强制完成!");
            postWms.setPostSt(WcsConstants.POST_STATUS_START);
            postWms.setCreator(WcsConstants.WCS_USER_ID);
            postWms.setUpdateDate(new Date());
            postWmsDao.insert(postWms);
            //如果任务类型是OT,还需要告知线体放货离开
            if (WcsConstants.TRK_TYPE_OT.equals(trkEntity.getTrkType())) {
                pcItemService.updateSingleByNo("PC_PUT_LEAVE_02", "True");
            }
        } else if (WcsConstants.TASK_MANUAL_CANCEL_OPERATE.equals(operateType)) {
//            判断任务状态是否能够取消
//            将状态设置为取消
            trkEntity.setTrkSt(WcsConstants.TRK_STATUS_ERROR);
            trkEntity.setComments("人工取消任务!");
            trkEntity.setUpdateDate(new Date());
        } else if (WcsConstants.TASK_MANUAL_DELETE_OPERATE.equals(operateType)) {

        } else {
            return new ProcResult().result("trkHandler_006", "作业类型不存在!");
        }
        baseDao.updateById(trkEntity);
        return new ProcResult().result("0", "success");
    }

    @Override
    public AgvTrkHkEntity getAgvHkTrkByTrkId(long id) {
        QueryWrapper<AgvTrkHkEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(AgvTrkHkEntity::getTrkId, id)
                .last("limit 1");
        return agvTrkHkDao.selectOne(qw);
    }

    @Override
    public AgvTrkYfEntity getAgvYfTrkByTrkId(long id) {
        QueryWrapper<AgvTrkYfEntity> qw = new QueryWrapper<>();
        qw.lambda().eq(AgvTrkYfEntity::getTrkId, id)
                .last("limit 1");
        return agvTrkYfDao.selectOne(qw);
    }
}
